#include <memory>
#include <string>
#include <iostream>
using namespace std;

// 针对文件这个特殊的对象类来说
// 删除器是没有设计出来的
// 需要自己手动写一个删除器
// 自定义删除器
void test(){
    string word = "hello,word111\n";
    FILE * fp = fopen("test.txt","a+");
    fwrite(word.c_str(),1,word.size(), fp);
    fclose(fp); // 手动关闭文件对象
}

// 把上面的逻辑给unique_ptr资源管理器管理
//
// unique_ptr 存在up.get()托管函数所以可以直接用这个
// 把文件指针托管给up
void test1(){
    string word = "hello,word222\n";
    unique_ptr<FILE> up(fopen("test.txt","a+"));
    fwrite(word.c_str(),1,word.size(), up.get());
    // 不需要自己在进行资源的手动释放
    // fclose(up.get()); 反而会导致double free
    // 因为在这些资源管理器中没有文件的管理设计
    // 这样写无法将内容输入到文件中去
}

// 手动写一个文件释放类
class fileDelete{
public:
    void operator()(FILE * fp){
        if(fp){
            fclose(fp);
        }
    }
};
void test2(){
    string word = "hello,word333\n";
    unique_ptr<FILE,fileDelete> up(fopen("test.txt","a+"));
    fwrite(word.c_str(),1,word.size(), up.get());
    // 不需要自己在进行资源的手动释放
    // fclose(up.get()); 反而会导致double free
}

// 使用shared_ptr资源管理器管理
// 也可以使用手动设置一个指针传入
void test3(){
    string word = "hello,word444\n";
    fileDelete fp;
    shared_ptr<FILE> sp(fopen("test.txt","a+"), fp);
    fwrite(word.c_str(),1,word.size(), sp.get());
    // 不需要自己在进行资源的手动释放
    // fclose(fd); 反而会导致double free
}

int main(int atgc, char * argv[])
{
    test();
    cout << "====================" << endl;
    test1();
    cout << "====================" << endl;
    test2();
    cout << "====================" << endl;
    test3();
    cout << "====================" << endl;
    return 0;
}

